package com.wm.wmim.server.service.wsmessage;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.wm.wmim.server.dto.bo.BaseMessageBody;
import com.wm.wmim.server.dto.bo.WsMessageBO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author weiming
 * @date 2024/8/29 20:56
 * @description
 */
@Service
public class WebSocketMessageHandleService {

    @Resource
    private List<AbstractWebSocketMessageHandleService> handleServiceList;

    private Map<String, AbstractWebSocketMessageHandleService> handleServiceMap;

    private static final ObjectMapper objectMapper = new ObjectMapper();

    static {
        // 禁用遇到未知属性抛出异常
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
        objectMapper.registerModule(javaTimeModule);
    }

    @PostConstruct
    private void postConstruct() {
        handleServiceMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(handleServiceList)) {
            for (AbstractWebSocketMessageHandleService handleService : handleServiceList) {
                handleServiceMap.put(handleService.getMessageType().getCode(), handleService);
            }
        }
    }

    public <Req extends BaseMessageBody, Resp extends WsMessageBO> String execute(String payload) {
        try {
            JsonNode rootNode = objectMapper.readTree(payload);
            // 读取messageType
            String reqMessageType = rootNode.get("messageType").asText();
            AbstractWebSocketMessageHandleService<Req, Resp> handleService = handleServiceMap.get(reqMessageType);
            if (handleService != null) {
                Class<Req> reqClass = handleService.getReqClass();
                // 读取并转换messageBody
                Req messageBody = null;
                if (rootNode.has("messageBody")) {
                    JsonNode messageBodyNode = rootNode.get("messageBody");
                    messageBody = objectMapper.treeToValue(messageBodyNode, reqClass);
                }
                WsMessageBO wsMessageBO = handleService.process(messageBody);
                if(wsMessageBO != null){
                    return JSONObject.toJSONString(wsMessageBO);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

}
